{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "rawdata={\n",
    "    'no surfacing':[1,1,1,0,0],\n",
    "    'flippers':[1,1,0,1,1],\n",
    "    'fish':['yes','yes','no','no','no']\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "df=pd.DataFrame(rawdata)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>no surfacing</th>\n",
       "      <th>flippers</th>\n",
       "      <th>fish</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>yes</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>yes</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>no</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>no</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>no</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   no surfacing  flippers fish\n",
       "0             1         1  yes\n",
       "1             1         1  yes\n",
       "2             1         0   no\n",
       "3             0         1   no\n",
       "4             0         1   no"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9709505944546686"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 计算熵\n",
    "def calEnt(df):\n",
    "    #计算最后一列的概率\n",
    "    num1=df.iloc[:,-1].value_counts(True)\n",
    "    #信息量\n",
    "    -np.log2(num1)\n",
    "    #熵\n",
    "    ent=np.sum(num1*-np.log2(num1))\n",
    "  \n",
    "    return ent\n",
    "calEnt(df)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "'''\n",
    "函数功能：\n",
    "    寻找最佳切分列\n",
    "'''\n",
    "\n",
    "def bestSplit(df):\n",
    "    baseEnt = calEnt(df)\n",
    "    bestCol = ''\n",
    "    bestGain = 0\n",
    "    infoGain = 0\n",
    "\n",
    "    # 循环 每一个 特征列：['no surfacing', 'flippers']\n",
    "    for col in df.columns[:-1]:\n",
    "\n",
    "        p_v = df[col].value_counts(True)\n",
    "        ent_v = []\n",
    "        # 当前 特征的 每一个取值：'no surfacing': [1, 0]\n",
    "        for col_value in p_v.index:\n",
    "            # 根据 当前特征值 筛选 行\n",
    "            ent_v.append(calEnt(df[df[col] == col_value]))\n",
    "\n",
    "        # 当前列的 熵\n",
    "        colEnt = (p_v * ent_v).sum()\n",
    "\n",
    "        infoGain = baseEnt - colEnt\n",
    "        # print(col, \"的 信息增益为：\", infoGain)\n",
    "        # 把 信息增益 最大的列，最为结果返回\n",
    "        if (infoGain > bestGain):\n",
    "            bestGain = infoGain\n",
    "            bestCol = col\n",
    "\n",
    "    return bestCol\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     True\n",
       "1     True\n",
       "2     True\n",
       "3    False\n",
       "4    False\n",
       "Name: no surfacing, dtype: bool"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['no surfacing'] == 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Int64Index([1, 0], dtype='int64')"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df['no surfacing'].value_counts(True).index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>no surfacing</th>\n",
       "      <th>flippers</th>\n",
       "      <th>fish</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>yes</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>yes</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>no</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   no surfacing  flippers fish\n",
       "0             1         1  yes\n",
       "1             1         1  yes\n",
       "2             1         0   no"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[df['no surfacing'] == 1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 按列 取值，删除 其行\n",
    "def mySplit(df,colName,value):\n",
    "    return df[df[colName]==value].drop(colName,axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'no surfacing'"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bestSplit(df)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def createTree(df):\n",
    "    # 【截止条件】：只剩一列（标签列） or 标签列取值 唯一\n",
    "    labelFreq = df.iloc[:,-1].value_counts(True)\n",
    "    if df.shape[1] == 1 or labelFreq[0] == 1:\n",
    "        # 返回概率最大的标签\n",
    "        return labelFreq.index[0]\n",
    "\n",
    "    # 找到 最佳切分列\n",
    "    bestCol = bestSplit(df)\n",
    "    # 建立 树\n",
    "    tree = {bestCol: {}}\n",
    "    # 当前列的 取值集合\n",
    "    value_set = set(df[bestCol])\n",
    "\n",
    "    for value in value_set:\n",
    "        # 递归建树\n",
    "        tree[bestCol][value] = createTree(mySplit(df, bestCol, value))\n",
    "    return tree"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "createTree(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tree=createTree(df)\n",
    "np.save('myTree.npy',tree)\n",
    "\n",
    "np.load('myTree.npy', allow_pickle=True).item()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def getValueFromTree(inX, Tree):\n",
    "    colName = next(iter(Tree))\n",
    "    colVal = inX[colName]\n",
    "    # tree[bestCol][value] = createTree(mySplit(df, bestCol, value))\n",
    "    # 取出对应特征列的值 的 子树\n",
    "    return Tree[colName][colVal]\n",
    "\n",
    "\n",
    "def classify(inX, Tree):\n",
    "    # 为 value 增加 key (特征值的col_name)\n",
    "    inX = dict(zip(df.columns[:-1], inX))\n",
    "\n",
    "    # 遍历子树，直到 叶子节点（即：非 dict 变量）\n",
    "    label = getValueFromTree(inX, Tree)\n",
    "    while type(label) == dict:\n",
    "        # 遍历下一层子树\n",
    "        label = getValueFromTree(inX, label)\n",
    "    return label"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Text(0.4, 0.8333333333333334, 'X[0] <= 0.5\\nentropy = 0.971\\nsamples = 5\\nvalue = [3, 2]'),\n",
       " Text(0.2, 0.5, 'entropy = 0.0\\nsamples = 2\\nvalue = [2, 0]'),\n",
       " Text(0.6, 0.5, 'X[1] <= 0.5\\nentropy = 0.918\\nsamples = 3\\nvalue = [1, 2]'),\n",
       " Text(0.4, 0.16666666666666666, 'entropy = 0.0\\nsamples = 1\\nvalue = [1, 0]'),\n",
       " Text(0.8, 0.16666666666666666, 'entropy = 0.0\\nsamples = 2\\nvalue = [0, 2]')]"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.datasets import load_iris\n",
    "from sklearn import tree\n",
    "\n",
    "\n",
    "\n",
    "clf = tree.DecisionTreeClassifier(criterion=\"entropy\")\n",
    "clf = clf.fit(np.array(df.iloc[:, :-1]), np.array(df.iloc[:, -1]))\n",
    "\n",
    "tree.plot_tree(clf)"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "a6dc62afd8b03c17538a9dfce2fcb18f62cec380cc7b77050462a64b7e4e4814"
  },
  "kernelspec": {
   "display_name": "Python 3.8.0 32-bit",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.2"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
